package br.uniceub.fsw.agenda.controller;

import br.uniceub.fsw.agenda.exception.BusinessException;
import br.uniceub.fsw.agenda.exception.ChildConstraintViolationException;
import br.uniceub.fsw.agenda.exception.DatabaseException;
import br.uniceub.fsw.agenda.model.vo.BairroVO;
import br.uniceub.fsw.agenda.model.vo.CidadeVO;
import br.uniceub.fsw.agenda.model.vo.MenuVO;
import br.uniceub.fsw.agenda.model.vo.TipoLogradouroVO;
import br.uniceub.fsw.agenda.model.vo.UFVO;
import br.uniceub.fsw.agenda.model.facade.ManterLogradouroFacade;
import br.uniceub.fsw.agenda.model.vo.LogradouroVO;
import br.uniceub.fsw.agenda.util.MutableHttpServletRequestWrapper;
import br.uniceub.fsw.agenda.util.HttpRequestWithModifiableParameters;
import br.uniceub.fsw.agenda.util.NumberUtils;
import br.uniceub.fsw.agenda.util.StringUtils;
import java.io.*;
import java.net.*;

import java.util.List;
import javax.servlet.*;
import javax.servlet.http.*;

/**
 *
 * @author Rodrigo Uchôa - rodrigo.uchoa@yahoo.com
 */
public class ManterLogradouroController extends GenericServlet {  
    private static final String LIST_LOGRADOUROS_CADASTRADOS = "listLogradourosCadastrados";
    
    public void iniciarTela(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession();
        
        String sgUf = request.getParameter("sgUf");
        Integer idCidade = NumberUtils.toInteger(request.getParameter("idCidade"));
        
        //Facades
        ManterLogradouroFacade facadeLogradouro = new ManterLogradouroFacade();
        
        try {
            //buscar lista de menus
            List<MenuVO> listMenu = facadeLogradouro.findAllMenu();
            request.setAttribute("listaDeMenu", listMenu);

            //buscar lista de ufs
            List<UFVO> listUF = facadeLogradouro.findAllUFs();
            request.setAttribute("listaDeUF", listUF);
            
            //uma UF foi selecionada, buscar todas as cidades da UF
            if (!StringUtils.isNullOrEmpty(sgUf)) {
                List<CidadeVO> listCidade = facadeLogradouro.findCidadesByUF(sgUf);
                request.setAttribute("listCidade", listCidade);                
            }
            
            //uma cidade foi selecionada, buscar todos os seus bairros
            if (idCidade != null) {
                List<BairroVO> listBairro = facadeLogradouro.findBairrosByCidade(idCidade);
                request.setAttribute("listBairro", listBairro);
            } 
            
            //buscar lista de tipos de logradouro
            List<TipoLogradouroVO> listTipoLogradouro = facadeLogradouro.findAllTiposLogradouro();
            request.setAttribute("listTipoLogradouro", listTipoLogradouro);
            
            //buscar todos os logradouros ja cadastrados
            List<LogradouroVO> listLogradourosCadastrados = (List<LogradouroVO>) session.getAttribute(LIST_LOGRADOUROS_CADASTRADOS);
            //carregar novamente se nao estiver na sessao
            if (listLogradourosCadastrados == null) {
                listLogradourosCadastrados = facadeLogradouro.findAllLogradourosCadastradosParaExibicao();                
                session.setAttribute(LIST_LOGRADOUROS_CADASTRADOS, listLogradourosCadastrados);                
            }            
            
        } catch (BusinessException ex) {          
            request.setAttribute("error", ex.getMessage());
        } catch (DatabaseException ex) {            
            request.setAttribute("error", "Erro de comunicação com o banco de dados.");
        }        
        RequestDispatcher rd = request.getRequestDispatcher("/manterLogradouro/manterLogradouro.jsp");
        rd.forward(request, response);        
    }   
    
    public void listar(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession();
        
        String sgUf = request.getParameter("sgUf");
        Integer idCidade = NumberUtils.toInteger(request.getParameter("idCidade"));
        String dsLogradouro = request.getParameter("dsLogradouro");
        Integer nrCep = NumberUtils.toInteger(request.getParameter("nrCep"));
        
        //Facades
        ManterLogradouroFacade facadeLogradouro = new ManterLogradouroFacade();
        
        try {
            //buscar lista de menus
            List<MenuVO> listMenu = facadeLogradouro.findAllMenu();
            request.setAttribute("listaDeMenu", listMenu);

            //buscar lista de ufs
            List<UFVO> listUF = facadeLogradouro.findAllUFs();
            request.setAttribute("listaDeUF", listUF);
            
            List<CidadeVO> listCidade = facadeLogradouro.findAllCidade(sgUf);
            request.setAttribute("listCidade", listCidade);
            
            List<BairroVO> listBairro = facadeLogradouro.findAllBairro(idCidade);
            request.setAttribute("listBairro", listBairro);
            
            //buscar todos os logradouros ja cadastrados
            List<LogradouroVO> listLogradourosCadastrados = (List<LogradouroVO>) session.getAttribute(LIST_LOGRADOUROS_CADASTRADOS);
            //carregar novamente se nao estiver na sessao
            listLogradourosCadastrados = facadeLogradouro.findAllLogradouro(dsLogradouro, nrCep);
            session.setAttribute(LIST_LOGRADOUROS_CADASTRADOS, listLogradourosCadastrados);                
            
        } catch (BusinessException ex) {          
            request.setAttribute("error", ex.getMessage());
        } catch (DatabaseException ex) {            
            request.setAttribute("error", "Erro de comunicação com o banco de dados.");
        }        
        RequestDispatcher rd = request.getRequestDispatcher("/manterLogradouro/manterLogradouro.jsp");
        rd.forward(request, response);        
    }   
    
    public void inserir(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //pegar parametros da tela
        String sgUf = request.getParameter("sgUf");
        Integer idCidade = NumberUtils.toInteger(request.getParameter("idCidade"));
        Integer idBairro = NumberUtils.toInteger(request.getParameter("idBairro"));
        Integer idTipoLogradouro = NumberUtils.toInteger(request.getParameter("idTipoLogradouro"));
        Integer nrCep = NumberUtils.toInteger(request.getParameter("nrCep"));
        String dsLogradouro = request.getParameter("dsLogradouro");
        
        //facade
        ManterLogradouroFacade facade = new ManterLogradouroFacade();
        
        //montar entidade que sera gravada
        LogradouroVO logradouro = new LogradouroVO();
        
        TipoLogradouroVO tipoLogradouro = new TipoLogradouroVO();
        CidadeVO cidade = new CidadeVO();
        BairroVO bairro = new BairroVO();
        
        tipoLogradouro.setIdTipoLogradouro(idTipoLogradouro);
        cidade.setIdCidade(idCidade);
        bairro.setIdBairro(idBairro);
        
        logradouro.setTipoLogradouro(tipoLogradouro);
        logradouro.setCidade(cidade);
        logradouro.setBairro(bairro);
        logradouro.setNrCep(nrCep);
        logradouro.setDsLogradouro(dsLogradouro);
        
        //passar um wrapper no lugar do verdadeiro request para limpar
        //os valores e exibir a tela com os campos limpos
        MutableHttpServletRequestWrapper wrapper = new MutableHttpServletRequestWrapper(request);
        
        try {
            facade.insertLogradouro(logradouro);
                        
            wrapper.setParametersToReset("sgUf", "idCidade", "idBairro", "idTipoLogradouro", "nrCep", "dsLogradouro");            
            //remover lista de cadastrados da sessao para que seja carregada novamente
            request.getSession().removeAttribute(LIST_LOGRADOUROS_CADASTRADOS);
            
        } catch (BusinessException ex) {
             request.setAttribute("error", ex.getMessage());            
        } catch (DatabaseException ex) {
             request.setAttribute("error", "Erro de comunicação com o banco de dados.");            
        }        
        iniciarTela(wrapper, response);
    }
    
    
    public void alterar(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //pegar parametros da tela
        String sgUf = request.getParameter("sgUf");
        Integer idCidade = NumberUtils.toInteger(request.getParameter("idCidade"));
        Integer idBairro = NumberUtils.toInteger(request.getParameter("idBairro"));
        Integer idTipoLogradouro = NumberUtils.toInteger(request.getParameter("idTipoLogradouro"));
        Integer nrCep = NumberUtils.toInteger(request.getParameter("nrCep"));
        Integer idLogradouro = NumberUtils.toInteger(request.getParameter("idLogradouro"));
        String dsLogradouro = request.getParameter("dsLogradouro");
        
        //facade
        ManterLogradouroFacade facade = new ManterLogradouroFacade();
        
        //montar entidade que sera gravada
        LogradouroVO logradouro = new LogradouroVO();
        
        TipoLogradouroVO tipoLogradouro = new TipoLogradouroVO();
        CidadeVO cidade = new CidadeVO();
        BairroVO bairro = new BairroVO();
        
        tipoLogradouro.setIdTipoLogradouro(idTipoLogradouro);
        cidade.setIdCidade(idCidade);
        bairro.setIdBairro(idBairro);
        
        logradouro.setIdLogradouro(idLogradouro);
        logradouro.setTipoLogradouro(tipoLogradouro);
        logradouro.setCidade(cidade);
        logradouro.setBairro(bairro);
        logradouro.setNrCep(nrCep);
        logradouro.setDsLogradouro(dsLogradouro);
        
        //passar um wrapper no lugar do verdadeiro request para limpar
        //os valores e exibir a tela com os campos limpos
        MutableHttpServletRequestWrapper wrapper = new MutableHttpServletRequestWrapper(request);
        
        try {
            facade.updateLogradouro(logradouro);
                        
            wrapper.setParametersToReset("sgUf", "idCidade", "idBairro", "idTipoLogradouro", "nrCep", "dsLogradouro");            
            //remover lista de cadastrados da sessao para que seja carregada novamente
            request.getSession().removeAttribute(LIST_LOGRADOUROS_CADASTRADOS);
            
        } catch (BusinessException ex) {
             request.setAttribute("error", ex.getMessage());            
        } catch (DatabaseException ex) {
             request.setAttribute("error", "Erro de comunicação com o banco de dados.");            
        }        
        iniciarTela(wrapper, response);
    }
    
    
    //TODO alterar ainda nao esta funcionando, terminar.
    public void consultar(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //id
        Integer idLogradouro = NumberUtils.toInteger(request.getParameter("idLogradouro"));
        
        ManterLogradouroFacade facade = new ManterLogradouroFacade();
        
        //passar um wrapper no lugar do verdadeiro request para limpar
        //os valores e exibir a tela com os campos limpos
        HttpRequestWithModifiableParameters wrapper = new HttpRequestWithModifiableParameters(request);
        
        try {            
            //buscar registro no banco
            LogradouroVO vo = facade.findLogradouroById(idLogradouro);
            
            //setar no request para ser exibido na tela            
            wrapper.setParameter("idLogradouro", vo.getIdLogradouro().toString());
            wrapper.setParameter("sgUf", vo.getCidade().getUf().getSgUf());
            wrapper.setParameter("idCidade", vo.getCidade().getIdCidade().toString());
            wrapper.setParameter("idBairro", vo.getBairro().getIdBairro().toString());
            wrapper.setParameter("idTipoLogradouro", vo.getTipoLogradouro().getIdTipoLogradouro().toString());
            wrapper.setParameter("dsLogradouro", vo.getDsLogradouro());
            wrapper.setParameter("nrCep", vo.getNrCep().toString());
            
        } catch (DatabaseException ex) {
            wrapper.setAttribute("error", "Erro de comunicação com o banco de dados.");
        }
        
        iniciarTela(wrapper, response);
    }
    
    public void excluir(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //id
        String idLogradouro = request.getParameter("idLogradouro");
        
        //facade
        ManterLogradouroFacade facade = new ManterLogradouroFacade();
        
        try {
            facade.deleteLogradouro(NumberUtils.toInteger(idLogradouro));
            
            //remover lista de cadastrados da sessao para que seja carregada novamente
            request.getSession().removeAttribute(LIST_LOGRADOUROS_CADASTRADOS);   
        } catch (ChildConstraintViolationException ex) {
            request.setAttribute("error", "Registro possui dependencias e nao pode ser deletado.");                                
        } catch (BusinessException ex) {
            request.setAttribute("error", ex.getMessage());            
        } catch (DatabaseException ex) {
            request.setAttribute("error", "Erro de comunicação com o banco de dados");
        }
        iniciarTela(request, response);        
    }
    
    public void limpar(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //passar um wrapper no lugar do verdadeiro request para limpar
        //os valores e exibir a tela com os campos limpos
        HttpRequestWithModifiableParameters wrapper = new HttpRequestWithModifiableParameters(request);
        
        wrapper.setParameter("idLogradouro", "");
        wrapper.setParameter("sgUf", "");
        wrapper.setParameter("idCidade", "");
        wrapper.setParameter("idBairro", "");
        wrapper.setParameter("idTipoLogradouro", "");
        wrapper.setParameter("dsLogradouro", "");
        wrapper.setParameter("nrCep", "");
            
        iniciarTela(wrapper, response);
    }
}
